package com.iaz.tech.tools.ai.neuron.exec;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iaz.tech.tools.ai.neuron.ability.INeuronAbility;
import com.iaz.tech.tools.ai.neuron.runtime.INeuronRuntimeAbility;
import com.iaz.tech.tools.common.utils.UtilTools;
import com.iaz.tech.tools.generator.java.INeuronSourceGenerateAble;
import com.iaz.tech.tools.message.impl.MessageForTalk;
import com.iaz.tech.tools.property.impl.PROPERTYRIGHT;
import com.iaz.tech.tools.property.project.Project;
import com.iaz.tech.tools.uml.IUMLNeuronAble;
import com.iaz.tech.tools.uml.relationship.Relationship;

import lombok.Data;

@Data
public abstract class NeuronCodeGenerator implements INeuronSourceGenerateAble {
    /**
     * 日志
     */
	private final static Logger logger = (Logger) LoggerFactory.getLogger(NeuronPackageCodeGenerator.class);
    /**
     * 机器人世界
     */
    private INeuronRuntimeAbility runtime; 

    /**
     * 转换为关系
     * @param uml
     * @return
     * @throws Exception
     */
    public abstract Relationship toRelationship(IUMLNeuronAble uml) throws Exception;

    /**
     * 生成代码
     */
    @Override
    public String generateSourceCode(Project project, IUMLNeuronAble uml) {
        String result = "";
        try {
            if (uml == null) {
                throw new IllegalArgumentException("uml不能为null");
            }
            
            if (this.getRuntime() == null){
                throw new IllegalArgumentException("runtime不能为null");
            }
            if (project == null) {
                throw new IllegalArgumentException("project不能为null");
            }
            Relationship aggregations = toRelationship(uml);
            
            if (!UtilTools.IsNull(aggregations.getDialingStr())) {
                /* 通信 */
                /* 主叫对象 */
                String dialing = aggregations.getDialingStr();
                if (UtilTools.IsNull(dialing)) {
                    throw new IllegalArgumentException("主叫对象不能为空。");
                }
                /* 寻找神经元， 发送消息 */
                INeuronAbility neuron_dialing = this.getRuntime().findByName(dialing);
                if (neuron_dialing == null){
                    throw new IllegalArgumentException("调用的神经元 " + dialing + " 不存在。");        
                }
                /* 发送消息 */
                MessageForTalk msg_talk = new MessageForTalk();
                msg_talk.setTalk( uml.toString() );
                neuron_dialing.talkMe(msg_talk);
            }
            
            if (!UtilTools.IsNull(aggregations.getCalledStr())){
                /* 被叫对象 */
                String called = aggregations.getCalledStr();
                if (UtilTools.IsNull(called)) {
                    throw new IllegalArgumentException("被叫对象不能为空。");
                }
                /* 寻找神经元， 发送消息 */
                INeuronAbility neuron_target = this.getRuntime().findByName(called);
                if (neuron_target == null){
                    throw new IllegalArgumentException("调用的神经元 " + called + " 不存在。");
                }
                MessageForTalk msg_talk = new MessageForTalk();
                msg_talk.setTalk( uml.toString() );
                neuron_target.talkMe(msg_talk);
            }
        } catch(Exception e) {
            logger.error("生成聚合代码失败", e);
        }
        return result;
    }

    /**
     * 生成属性权限
     * @param right
     * @return
     */
    public String generatorPropertyRight(PROPERTYRIGHT right) {
        String result = "";
        switch (right) {
            case nprivate:
                result = "private";
                break;
            case nprotected:
                result = "protected";
                break;
            case npublic:
                result = "public";
                break;
            default:
                result = "private";
                break;
        }
        return result;
    }

    public String generatorPropertyType(Boolean is_SignAbstract, Boolean is_SignFinal, Boolean is_SignStatic ) {
        String result = "";
        StringBuffer sBuf = new StringBuffer();
        if (is_SignAbstract) {
            sBuf.append("   abstract ");
        }
        if (is_SignFinal) {
            sBuf.append("   final ");
        }
        if (is_SignStatic) {
            sBuf.append("   static ");
        }

        result = sBuf.toString();
        return result;
    }
}
